﻿using Facebook;
using Infoware.Strings;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SocialCommercials
{

    public class dataModel
    {
        public string[] messages { get; set; }
        public string[] groups { get; set; }
        public int time { get; set; }
    }


    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        
        public MainWindow()
        {
            InitializeComponent();
            string data = "";
            if (File.Exists(@".\settings.txt"))
                data = File.ReadAllText(@".\settings.txt");
            if (!string.IsNullOrWhiteSpace(data))
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                dataModel model = serializer.Deserialize<dataModel>(data);
                foreach (string str in model.messages)
                {
                    txtMessage.Text += str + "|||";
                }
                if (!string.IsNullOrWhiteSpace(txtMessage.Text))
                    txtMessage.Text = txtMessage.Text.Substring(0, txtMessage.Text.Length - 3);
                foreach (string str in model.groups)
                {
                    txtGroups.Text += str + "\r\n";
                }
                if (!string.IsNullOrWhiteSpace(txtGroups.Text))
                    txtGroups.Text = txtGroups.Text.Substring(0, txtGroups.Text.Length - 2);
                txtTime.Text = (model.time/1000).ToString();
            }

            this.Closing += MainWindow_Closing;
        }

        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Button_Click_2(sender, null);
        }

        Thread currentOne = null;

       

        string appID = "";
        string appSecret = "";

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            
            appID = System.Configuration.ConfigurationManager.AppSettings["Facebook.AppId"];
            appSecret = System.Configuration.ConfigurationManager.AppSettings["Facebook.AppSecret"];
            string url = string.Format("https://www.facebook.com/dialog/oauth?client_id={0}&client_secret={1}&redirect_uri={2}&response_type=token&scope=publish_actions+publish_stream+user_groups+user_events+user_activities+user_notes+user_photos+read_stream", appID, appSecret, "http://shohdiblog.tk");
            webBrowser.LoadCompleted += webBrowser_LoadCompleted;
            webBrowser.Navigate(url);
            
            
        }

        void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            if (!e.Uri.ToString().StartsWith("https://www.facebook.com"))
            {
                string uri = e.Uri.ToString();

                Regex reg = new Regex(Regex.Escape("access_token=") + "[^" + Regex.Escape("&") + "]+");
                string accessToken =  reg.Match(uri.ToString()).Value.Replace("access_token=", "");

                

                FacebookClient client = new FacebookClient(accessToken);
                dynamic me = client.Get("oauth/access_token", new { grant_type = "fb_exchange_token"
                    , client_id=appID
                    ,client_secret = appSecret
                    ,fb_exchange_token=accessToken
                });

                accessToken = me.access_token;

                doWork(appID, appSecret,accessToken, sender, null);
            }
        }

        private void doWork(string appID,string appSecret,string accessToken,object sender, RoutedEventArgs e)
        {
            string message = "";
            string[] groups = null;
            int time = 3600000;
            
            dataModel model = new dataModel();
            try
            {
                message = txtMessage.Text;
                groups = txtGroups.Text.Split(new string[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
                time = int.Parse(txtTime.Text) * 1000;
               
                model = new dataModel()
                {
                    messages = message.Split(new string[]{"|||"},StringSplitOptions.RemoveEmptyEntries)
                    ,
                    groups = groups
                    ,
                    time = time
                };

                JavaScriptSerializer serializer = new JavaScriptSerializer();
                string data = serializer.Serialize(model);
                File.WriteAllText(@".\settings.txt", data);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }

            Button_Click_2(sender, e);


            currentOne = new Thread(() =>
            {

                postMessageOnFacebook(model, appID, appSecret,accessToken);


            });

            currentOne.Start();
        }


        private static List<string> AllUserGroups = new List<string>();

        private void postMessageOnFacebook(dataModel model, string appID, string appSecret,string acessToken)
        {
            int i = 0;

            FacebookClient clientLogged = new FacebookClient(acessToken);

            GetUser( appID, appSecret, acessToken, clientLogged);

            GetGroups(model, appID, appSecret, acessToken, clientLogged);

            if (model.groups == null || model.groups.Length == 0)
            {
                model.groups = AllUserGroups.ToArray();
            }

            while (true)
            {

                foreach (string group in model.groups)
                {
                    object messageObj = createMethod(model,acessToken, i);
                    postMessageOnFacebookOneGroup(messageObj, group, appID, appSecret, acessToken,model.time);

                    Thread.Sleep(model.time);
                    addToUserTimeLine(appID, appSecret, acessToken, messageObj);

                    Thread.Sleep(model.time);
                }


                i = (i + 1) % model.messages.Length;
                Thread.Sleep(model.time);
            }
        }

        private static void addToUserTimeLine(string appID, string appSecret, string acessToken, object messageObj)
        {
            FacebookClient clientLoggedUser = new FacebookClient(acessToken);
            try
            {
                clientLoggedUser.Post(string.Format("/{0}/feed", userId), messageObj);
            }
            catch (Exception ex)
            {
                logException(ex, "feed", messageObj, userId, appID, appSecret, acessToken);
            }
        }

        private static void GetGroups(dataModel model, string appID, string appSecret, string acessToken, FacebookClient clientLogged)
        {
            try
            {

                dynamic groups = clientLogged.Get(string.Format("/{0}/groups", userId), new { limit = 200 });

                for (int gIndex = 0; gIndex < groups.data.Count; gIndex++)
                {
                    AllUserGroups.Add(groups.data[gIndex].id);
                }


            }
            catch (Exception ex)
            {
                logException(ex, "GetGroups", model, appID, appSecret, acessToken);
            }
        }

        private static object createMethod(dataModel model, string acessToken, int i)
        {
            object messageObj = new { message = "", link = "" };
            string[] messageObjArr = model.messages[i].Split(new string[]{"||"},StringSplitOptions.RemoveEmptyEntries);
            if (messageObjArr.Length == 1)
            {
                messageObj = new { message = messageObjArr[0].Trim(), link = "", picture="", access_token = acessToken  };
            }
            else if (messageObjArr.Length == 2)
            {
                messageObj = new { message = messageObjArr[0].Trim(), link = messageObjArr[1].Trim(), picture = "", access_token = acessToken };
            }
            else if (messageObjArr.Length > 2)
            {
                messageObj = new { message = messageObjArr[0].Trim(), link = messageObjArr[1].Trim(), picture = messageObjArr[2].Trim(), access_token = acessToken };
            }
            return messageObj;
        }


        public static string convertToString(params object[] parameters)
        {
            var obj = new { Parameters = parameters };

            JavaScriptSerializer serializer = new JavaScriptSerializer();

            return serializer.Serialize(obj);
        }

        private static string userName = "";
        private static string userId = "";

        private void postMessageOnFacebookOneGroup(object message, string group, string appID, string appSecret, string acessToken,int time)
        {
            FacebookClient clientLogged = new FacebookClient(acessToken);




            try
            {
                dynamic ret = clientLogged.Get(string.Format("/{0}/feed", group), new { limit = 10, access_token = acessToken });

                bool found = false;
                for (int mesIndex = 0; mesIndex < ret.data.Count; mesIndex++)
                {
                    string currentMessage = ret.data[mesIndex].message;
                    currentMessage = StringsManipulation.txtAbstract(currentMessage);
                    string newOne = StringsManipulation.txtAbstract(message.GetType().GetProperty("message").GetValue(message).ToString());
                    if (currentMessage.Equals(newOne))
                        found = true;
                    
                }


                if (!found)
                {
                    try
                    {
                        clientLogged.Post(string.Format("/{0}/feed", group), message);
                    }
                    catch (Exception ex)
                    {
                        logException(ex, "feed", message, group, appID, appSecret, acessToken);
                    }
                    Thread.Sleep(time);
                }


            }
            catch (Exception ex)
            {
                logException(ex, "feed", message, group, appID, appSecret, acessToken);
            }




            try
            {

                dynamic ret = clientLogged.Get(string.Format("/{0}/feed", group), new { limit = 10, access_token = acessToken });
                string newCommentMessage = message.GetType().GetProperty("message").GetValue(message).ToString() + " " +
                            message.GetType().GetProperty("link").GetValue(message).ToString();
                
                if (ret.data.Count > 0)
                {
                
                    bool found = false;


                    string currentMessage = ret.data[0].message;
                    currentMessage = StringsManipulation.txtAbstract(currentMessage);
                    string newOne = StringsManipulation.txtAbstract(message.GetType().GetProperty("message").GetValue(message).ToString());
                    if (currentMessage.Equals(newOne))
                        found = true;

                    if ((!found) && ret.data[0].comments != null)
                    {

                        for (int comIndex = 0; comIndex < ret.data[0].comments.data.Count; comIndex++)
                        {
                            currentMessage = ret.data[0].comments.data[comIndex].message;


                            currentMessage = StringsManipulation.txtAbstract(currentMessage);
                            string absMes = StringsManipulation.txtAbstract(newCommentMessage);

                            if (currentMessage.Equals(absMes))
                                found = true;

                        }
                    }


                    if ((!found) && ConfigurationManager.AppSettings["Facebook.IsComment"].Equals("True",StringComparison.OrdinalIgnoreCase))
                    {

                        string id = ret.data[0].id.ToString();

                        try
                        {
                            clientLogged.Post(string.Format("/{0}/comments", id), new
                            {
                                message = newCommentMessage
                                ,
                                attachment_url = message.GetType().GetProperty("picture").GetValue(message).ToString()

                            });
                        }
                        catch (Exception ex)
                        {
                            logException(ex, "comment", message, group, appID, appSecret, acessToken);
                        }

                        Thread.Sleep(time);
                    }


                }



               

            }
            catch (Exception ex)
            {


                logException(ex, "comment", message, group, appID, appSecret, acessToken);
            }

           


           
           


            

            
        }

        private static void GetUser( string appID, string appSecret, string acessToken, FacebookClient clientLogged)
        {
            try
            {
                dynamic user = clientLogged.Get("me", new { access_token = acessToken });
                userId = user.id.ToString();
                userName = user.username;
            }
            catch (Exception ex)
            {
                logException(ex, "GetUser", appID, appSecret, acessToken);
            }
        }

        private static void logException(Exception ex,params object[] parameters)
        {
            try
            {
                string param = "";
                try { param = convertToString(parameters); }
                catch { }
                string Guid = System.Guid.NewGuid().ToString();
                DateTime dt = DateTime.Now;
                string dir = @".\Errors\" + "Hour_" + dt.Hour.ToString() + @"\";
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                string file = dir + Guid + ".txt";
                File.WriteAllText(file, param + "\r\n" + ex.ToString());
            }
            catch
            {
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            if (currentOne != null)
                if (currentOne.ThreadState == ThreadState.Running)
                    currentOne.Abort();
        }
    }
}
